﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Gunningine
{
    /// <summary>
    /// Camera class, for describing view.
    /// </summary>
    public class Camera
    {
        public Vector3 Position { get; internal set; }

        public Vector3 Direction { get; internal set; }

        public Vector3 Up { get; internal set; }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="position">camera position.</param>
        /// <param name="direction">camera viewing direction.</param>
        /// <param name="up">camera up vector.</param>
        internal Camera(Vector3 position, Vector3 direction, Vector3 up)
        {
            this.Position = position;
            this.Direction = direction;
            this.Up = up;
        }

        /// <summary>
        /// Move the camera in the direction that it is facing.
        /// </summary>
        /// <param name="distance"></param>
        public void travel(float distance)
        {
            this.Position += this.Direction * distance;
        }

        /// <summary>
        /// Pan camera the specified distance, relative to its orientation.
        /// </summary>
        /// <param name="xDist">x distance.</param>
        /// <param name="yDist">y distance.</param>
        public void pan(float xDist, float yDist)
        {
            Vector3 side = Vector3.CrossProduct(this.Direction, this.Up);

            this.Position += side * xDist;
            this.Position += this.Up * yDist;
        }

        /// <summary>
        /// Rotate the camera around its up vector.
        /// </summary>
        /// <param name="angle">angle to rotate by.</param>
        public void yaw(float angle)
        {
            this.Direction = Vector3.Rotate(this.Direction, angle, this.Up);
        }

        /// <summary>
        /// Rotate the camera around its up vector.
        /// </summary>
        /// <param name="angle">angle to rotate by.</param>
        public void pitch(float angle)
        {
            Vector3 side = Vector3.CrossProduct(this.Direction, this.Up);
            this.Direction = Vector3.Rotate(this.Direction, angle, side);
        }

        /// <summary>
        /// Roll the camera.
        /// </summary>
        /// <param name="angle">angle to rotate by.</param>
        public void roll(float angle)
        {
            this.Up = Vector3.Rotate(this.Up, angle, this.Direction);
        }
    }
}
